package com.chis.gencode;

import com.alibaba.fastjson.JSON;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;


import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class ZXingUtil {


    public static void main(String[] args) throws Exception {
//        genaratecode();
//        parascode();
    }

    public static void parascode() throws Exception{
//        String basedate = "Rtwsst5U14yaoHE8Udno2gSokUoYAvai8gXFndlSG9/aTCYSgLzA/TKQ84sA66FE7YJW2YorSP5ysgZfZsqxCujAz59UmqUdhYyOxv6Q0joyH+OZg6yK5C59xyx+XSvDcoqcK2LbZ++zJVz2gEIXhOLFzqhMSIfdd+hZPdbm3NLey6F2rNhb0QVYnaTHsjwZ8LWAae9UZ5OXrU7MegWNLhPyIg+sP8SvDBs+7CpImYU=";
//        String basedate = "N7e0zJbQk0qJj2IX0nl4thlx7ZFEWCcI7x7vA4wdSPJZsRTQqCnxvNuIylAF2ibLDTJUmEimgky+4T94Dszh+Yti9bfRCxT0GyX0Qd44jkISJnfomOtC/O/wr4gl9e0rvrn5yaiuF6xKEqTRVBORjlBVDxUJUWmJvDPk5FzG+X+vMGz8A2R/AtPXq4Yn/9pyNsPciHUTADDujq2jUIaShXvfzBtukNp1mWWfNAxMz+j/S+8ovv0Ch53SY3DIQK5x03OhL542fRr8wALptoj3o9/S+W8Jr5lFPlxruf+qXoM+vIeT55bu/eq8cfwZoznH31tHaoNYUUPNV8C32l6t4uL39jWYpz70r3KYU/xhQ6mdMsnxYVKp7JFHlg55QVWo6sSIdrC/fHdOoL8GenZYuBOLwR82OypwMXnYQOmNfHCyZ8SL2iWkY14PgRLCV3M/ymcVneqQzbUAMq+YvD21qimzC8wi83zT+AO3cv0Gt0U=";
        String basedate = "e/xJ3K81QP/DWd78Z2JQn8i4BOiI9/ZVnJr+F0nt8aGgsm3tRx3s1ptenUTBiuREQfgRDgQ6DSJeBUSvR8VSUuM7T2rI/iqEqT+cqlSdzepNrD7ufwhTnMgUBe4zyYBHrlerXNCjdbW12hLJHXC8KDtIJNU+RHYRvphV84OKA8HaVeYnZpd6Hh0fTHUksT/bU7PjLJoH22jB32RPRogCeIPnLOKwJq4146QBeUPOazB+oO05NKAWNNWQwpiLbB1y1kABrQeCMmrTjhBGaGWYKWVKWRZwwzg7+rzzbJv8gz791UsEVf8K22RdJSnHcTypCOJSZ/HOck1n/5MjRdH6KzlqkYYwOnpfT7V6yzcb8DeYZJFEGBgrRqKxNB1eR+UjiiHZdl1fAVS039JhQp7omRW7Zdlq+83fzfcTOt9lQqWVZcgHrnWtDdF67jyXPYJnPmOB3fPwvUa3OsnJI7PdnD8Jf928KTRtWVLoaeCCrOECo6NjUxp+sOlTqA9UGHVR";
        //解码
        byte[] decode = Base64.getDecoder().decode(basedate);
        //解密
        byte[] decrypt = decrypt(decode, "1234");
        //解压缩
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(decrypt);
        GZIPInputStream gzipInputStream = new GZIPInputStream(in);
        byte[] buffer = new byte[256];
        int n;
        while ((n = gzipInputStream.read(buffer)) >= 0) {
            out.write(buffer, 0, n);
        }
        String data = out.toString("UTF-8");
        System.out.println(data);

    }


    public static void genaratecode() throws Exception{
        String imgPath = "C:\\Users\\wlj\\Desktop\\zxing\\1.png";
        Vaccine vaccinMain = new Vaccine();
        vaccinMain.setOpttype(1);
        vaccinMain.setStorename("1号冷库");
        List<Vaccinesub> list1 = new ArrayList<>();
        Vaccinesub vaccinInfo = new Vaccinesub();
        vaccinInfo.setVaccicode("86900160000966");
        vaccinInfo.setBatnmb("201905201-1");
        vaccinInfo.setVaccinum(2000);
        vaccinInfo.setProudate("2019-10-12");
        vaccinInfo.setInvaldate("2021-10-11");
        list1.add(vaccinInfo);
        vaccinInfo = new Vaccinesub();
        vaccinInfo.setVaccicode("86900160000905");
        vaccinInfo.setBatnmb("201901021-2");
        vaccinInfo.setVaccinum(5000);
        vaccinInfo.setProudate("2019-10-12");
        vaccinInfo.setInvaldate("2021-10-11");
        list1.add(vaccinInfo);
        vaccinMain.setVacclist(list1);

        String content = JSON.toJSONString(vaccinMain);
        System.out.println(content);
        //压缩
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        gzip.write(content.getBytes("UTF-8"));
        gzip.close();
        byte[] gzipdata = out.toByteArray();
        //加密
        byte[] crypt = encrypt(gzipdata,"1234");
        //base64编码
        String basedate = Base64.getEncoder().encodeToString(crypt);
        System.out.println(basedate);
        //二维码
        ZXingUtil.encodeImg(imgPath, "png",basedate, 500, 500,null);
    }

    public static byte[] encrypt(byte[] content, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
            kgen.init(128, new SecureRandom(password.getBytes()));// 利用用户密码作为随机数初始化出
            byte[] enCodeFormat = kgen.generateKey().getEncoded();// 返回基本编码格式的密钥，如果此密钥不支持编码，则返回
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(enCodeFormat, "AES"));// 初始化为加密模式的密码器
            return cipher.doFinal(content);// 加密
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] decrypt(byte[] content, String password) throws Exception{
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者
            kgen.init(128, new SecureRandom(password.getBytes()));
            byte[] enCodeFormat = kgen.generateKey().getEncoded();// 返回基本编码格式的密钥
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(enCodeFormat, "AES"));// 初始化为解密模式的密码器
            return cipher.doFinal(content);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    public static void encodeImg(String imgPath,String format,String content,int width,int height,String logo) throws Exception {
        Hashtable<EncodeHintType,Object > hints = new Hashtable<>() ;
        //排错率  L<M<Q<H
        hints.put( EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M) ;
        //编码
        hints.put( EncodeHintType.CHARACTER_SET, "utf-8") ;
        //外边距：margin
        hints.put( EncodeHintType.MARGIN, 0) ;
        /*
         * content : 需要加密的 文字
         * BarcodeFormat.QR_CODE:要解析的类型（二维码）
         * hints：加密涉及的一些参数：编码、排错率
         */
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,width,height, hints);

        //返回图片字节码
//        ByteArrayOutputStream os = new ByteArrayOutputStream();
//        MatrixToImageWriter.writeToStream(bitMatrix, "png", os);
//        return os.toByteArray();

        //文件落地保存
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        for(int x=0;x<width;x++) {
            for(int y=0;y<height;y++) {
                image.setRGB(x, y,  (bitMatrix.get(x,y)?0:16777215)  );
            }
        }
        File file = new File(imgPath);
        ImageIO.write(image, format, file);
    }

    //解密：二维码->文字
    public static void decodeImg(File file) throws Exception {
        if(!file.exists()) return ;
        //file->内存中的一张图片
        BufferedImage imge = ImageIO.read(file)  ;

        MultiFormatReader formatReader = new MultiFormatReader() ;
        LuminanceSource source = new BufferedImageLuminanceSource(imge);
        Binarizer binarizer = new HybridBinarizer(source);
        BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
        //图片 ->result
        Map map = new HashMap();
        map.put(EncodeHintType.CHARACTER_SET, "utf-8") ;
        Result result = formatReader.decode(binaryBitmap  ,map ) ;
        System.out.println("解析结果："+ result.toString());
    }

}